﻿using System.Collections;
using System.Collections.Generic;
using System.Runtime.Remoting.Contexts;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

namespace XFFSM
{
    public class Context
    {

        #region 字段

        private RuntimeFSMController _runtimeFSMController;

        public List<FSMStateNodeData> SelectNodes = new List<FSMStateNodeData>();

        public FSMTransitionData selectTransition;

        public bool isPreviewTransition = false;
        public FSMStateNodeData fromState = null;
        public FSMStateNodeData hoverState = null;

        private FSMController _FSMController;

        private LayoutMatrix4x4Info _matrixInfo;

        private static Context _instance;
          
        #endregion

        #region 属性
        public float ZoomFactor { get; set; } = 0.3f;

        public Vector2 DragOffset { get; set; }


        
        // 这个逻辑修改为如果只有一个,逻辑不变,
        // 如果有多个,判断当前显示的是不是在多个中,如果在不做处理,如果不在设置为第一个
        public RuntimeFSMController RuntimeFSMController {
            get 
            {
                if (_runtimeFSMController == null)
                {
                    string path = AssetDatabase.GUIDToAssetPath(RuntimeFSMControllerGUID);
                    _runtimeFSMController = AssetDatabase.LoadAssetAtPath<RuntimeFSMController>(path);
                }

                if (_runtimeFSMController == null && RuntimeFSMControllers != null)
                {
                    if (RuntimeFSMControllers.Count == 0) return null;
                    if (FSMControllerIndex < 0 || FSMControllerIndex >= RuntimeFSMControllers.Count) 
                        FSMControllerIndex = 0;
                    return RuntimeFSMControllers[FSMControllerIndex];
                }

                return _runtimeFSMController;
            }
            internal set 
            {
                if (_runtimeFSMController == value) return;
                Reset();
                _runtimeFSMController = value;
            }
        }

        public FSMController FSMController {
            get {

                if (_FSMController == null)
                {
                    GameObject gameObj = EditorUtility.InstanceIDToObject(FSMControllerInstanceID) as GameObject;
                    if (gameObj == null) return null;
                    _FSMController = gameObj.GetComponent<FSMController>();
                }

                return _FSMController;
            }
        }
 

        private List<RuntimeFSMController> currentFSMControllers = new List<RuntimeFSMController> ();

        public List<RuntimeFSMController> RuntimeFSMControllers
        {
            get 
            {
                if (FSMController != null)
                    return FSMController.RuntimeFSMController;
                currentFSMControllers.Clear();

                if (_runtimeFSMController == null)
                {
                    string path = AssetDatabase.GUIDToAssetPath(RuntimeFSMControllerGUID);
                    _runtimeFSMController = AssetDatabase.LoadAssetAtPath<RuntimeFSMController>(path);
                }

                if (_runtimeFSMController != null)
                    currentFSMControllers.Add(_runtimeFSMController);
                return currentFSMControllers;
            }
        }



        public static Context Instance
        {
            get {
                if(_instance == null) 
                    _instance = new Context();
                return _instance;
            }
        }

        internal int FSMControllerInstanceID
        {
            get 
            {
                return PlayerPrefs.GetInt("XFFSMControllerInstanceID",0);
            }
            set {
                PlayerPrefs.SetInt("XFFSMControllerInstanceID", value);
                Object obj = EditorUtility.InstanceIDToObject(value);
                GameObject gameObj = obj as GameObject;
                if (gameObj != null && gameObj.GetComponent<FSMController>() != null) { 
                    _FSMController = gameObj.GetComponent<FSMController>(); 
                }
                else
                    _FSMController = null;
                
            }
        }

        internal string RuntimeFSMControllerGUID
        {
            get
            {
                return PlayerPrefs.GetString("XFFSMRuntimeFSMControllerGUID",string.Empty);
            }
            set {
                PlayerPrefs.SetString("XFFSMRuntimeFSMControllerGUID", value);
                string path  = AssetDatabase.GUIDToAssetPath(value); 
                RuntimeFSMController = AssetDatabase.LoadAssetAtPath<RuntimeFSMController>(path); 
            }
        }

        internal int FSMControllerIndex
        {
            get { 
                return PlayerPrefs.GetInt("FSMControllerIndex", 0);
            }
            set
            {
                if (FSMControllerIndex == value) return;
                PlayerPrefs.SetInt("FSMControllerIndex", value);
                Reset();
            }
        }

        #endregion

        #region 方法

        private Context() {
        }

        public void Reset() 
        {
            // 重置缩放和偏移
            this.ZoomFactor = 0.3f;
            this.DragOffset = Vector2.zero;
            _matrixInfo = null;
        }
 
        public void ClearSelections()
        {
            // 如果不是 InspectorWindow 此时清空 Inspector
            this.SelectNodes.Clear();
            selectTransition = null;
            Selection.activeObject = null;
            //Selection.activeObject = this.RuntimeFSMController;
        }

        public void StartPreviewTransition(FSMStateNodeData node) {
            this.fromState = node;
            this.isPreviewTransition = true;
        }

        public void StopPreviewTransition() {
            this.fromState = null;
            this.isPreviewTransition = false;
        }

        public LayoutMatrix4x4Info GetMatrixInfo(Rect position) {
            if (_matrixInfo == null) 
                _matrixInfo = new LayoutMatrix4x4Info(this, position.center);
             
            return _matrixInfo;
        }
         
        #endregion
    }


    public class LayoutMatrix4x4Info 
    {

        public Vector2 center; 
        public Matrix4x4 matrix;
        private Context context;
         

        public LayoutMatrix4x4Info(Context context,Vector2 point)
        {
            this.context = context;
            center = point + context.DragOffset;
            matrix = Matrix4x4.TRS(center, Quaternion.identity, Vector3.one * context.ZoomFactor);
             
        }

        public void UpdateCenter(Vector2 detal) 
        {
            center += detal;
            matrix = Matrix4x4.TRS(center, Quaternion.identity, Vector3.one * context.ZoomFactor);
 
        }

        public void UpdateScale() {
            matrix = Matrix4x4.TRS(center, Quaternion.identity, Vector3.one * context.ZoomFactor); 
        }

        public void ChangeCenter(Vector2 center) 
        {
            if (center == this.center) return;
              
            if (context.RuntimeFSMController == null)
                return; 
            

            // 把中心点转换成相对于旧中心点的坐标 
            Vector2 centerPos = TransScreenPointToLocalPosition(center);
            // 然后把每一个节点的坐标转换成相对于新的中心点的坐标
            foreach (var state in context.RuntimeFSMController.states)
            {
                Rect rect = new Rect();
                rect.position = state.rect.position - centerPos;
                rect.size = state.rect.size;
                state.rect = rect;
            }

            // 修改线的中心点坐标
            context.RuntimeFSMController.lineCenterPosition -= centerPos;

            context.RuntimeFSMController.Save();

            this.center = center;
            matrix = Matrix4x4.TRS(center, Quaternion.identity, Vector3.one * context.ZoomFactor);
        }


        public Vector2 TransScreenPointToLocalPosition(Vector2 point)
        {
            Vector2 p = point - this.center;
            p /= this.context.ZoomFactor;
            return p;
        }
    }

}

